/**
 * Created by FreezeSoul on 2017/9/6.
 */
define([
    "app/core/base",
    "app/core/util",
    "../commonMeta",
    "jquery",
    "underscore",
    'JSONParse',
    'loglevel',
    'raphael',
    'treantJs',
    'css!app/plugins/controls/common/organizational/resource/style.css'
], function (Chart, Util, Meta, $, _, JSON, log, Raphael) {

    var property = {
        config: "property",
        option: [
            {
                group: '基础',
                id: 'Tree_LineWidth',
                name: '连接线宽度',
                enable: false,
                type: 'number',
                value: 2,
                default: 2,
                link: 'lineWidth',
                tooltip: '连接线宽度'
            }, {
                group: '基础',
                id: 'Tree_LineColor',
                name: '连接线颜色',
                enable: false,
                type: 'color',
                value: '#000000',
                default: '#000000',
                link: 'lineColor',
                tooltip: '连接线颜色'
            }, {
                group: '基础',
                id: 'Tree_Orientation',
                name: '组织树朝向',
                enable: false,
                type: 'select',
                value: 'NORTH',
                default: 'NORTH',
                data: [{
                    value: 'NORTH',
                    text: 'NORTH'
                }, {
                    value: 'EAST',
                    text: 'EAST'
                }, {
                    value: 'WEST',
                    text: 'WEST'
                }, {
                    value: 'SOUTH',
                    text: 'SOUTH'
                }],
                link: 'orientation',
                tooltip: '组织架构树朝向'
            },
            {
                group: '基础',
                id: 'Tree_StackChildren',
                name: '子节点堆叠',
                enable: true,
                type: 'checked',
                value: true,
                default: true,
                link: 'stackChildren',
                tooltip: '堆叠排放子节点'
            },
            {
                group: '基础',
                id: 'Tree_BorderWidth',
                name: '节点边框宽度',
                enable: false,
                type: 'number',
                value: 1,
                default: 1,
                link: 'borderWidth',
                tooltip: '节点边框宽度'
            }, {
                group: '基础',
                id: 'Tree_BorderColor',
                name: '节点边框颜色',
                enable: false,
                type: 'color',
                value: '#000000',
                default: '#000000',
                link: 'borderColor',
                tooltip: '节点边框颜色'
            },
            {
                group: '基础',
                id: 'Tree_BorderRadius',
                name: '边框圆角弧度',
                enable: false,
                type: 'number',
                value: 5,
                default: 5,
                link: 'borderRadius',
                tooltip: '节点边框圆角弧度'
            },
            {
                group: '基础',
                id: 'Tree_NodeWidth',
                name: '节点宽度',
                enable: false,
                type: 'number',
                value: 250,
                default: 250,
                link: 'nodeWidth',
                tooltip: '节点宽度'
            }, {
                group: '基础',
                id: 'Tree_NodeHeight',
                name: '节点高度',
                enable: false,
                type: 'number',
                value: 100,
                default: 100,
                link: 'nodeHeight',
                tooltip: '节点高度'
            },
            {
                group: '基础',
                id: 'Tree_BackgroundColor',
                name: '节点背景色',
                enable: false,
                type: 'color',
                value: '#ffffff',
                default: '#ffffff',
                link: 'backgroundColor',
                tooltip: '节点背景色'
            }, {
                group: '基础',
                id: 'Tree_NodeImageWidth',
                name: '头像宽度',
                enable: false,
                type: 'number',
                value: 64,
                default: 64,
                link: 'nodeImageWidth',
                tooltip: '头像宽度'
            }, {
                group: '基础',
                id: 'Tree_NodeImageHeight',
                name: '头像高度',
                enable: false,
                type: 'number',
                value: 64,
                default: 64,
                link: 'nodeImageHeight',
                tooltip: '头像高度'
            },
            {
                group: '基础',
                id: 'Tree_NodeNameSize',
                name: '标题字体大小',
                enable: false,
                type: 'number',
                value: 12,
                default: 12,
                link: 'nodeNameSize',
                tooltip: '标题字体大小'
            }, {
                group: '基础',
                id: 'Tree_NodeDescSize',
                name: '描述字体大小',
                enable: false,
                type: 'number',
                value: 12,
                default: 12,
                link: 'nodeDescSize',
                tooltip: '描述字体大小'
            }, {
                group: '基础',
                id: 'Tree_NodeNameColor',
                name: '标题字体颜色',
                enable: false,
                type: 'color',
                value: '#000000',
                default: '#000000',
                link: 'nodeNameColor',
                tooltip: '标题字体颜色'
            }, {
                group: '基础',
                id: 'Tree_NodeDescColor',
                name: '描述字体颜色',
                enable: false,
                type: 'color',
                value: '#333333',
                default: '#333333',
                link: 'nodeDescColor',
                tooltip: '描述字体颜色'
            },
            {
                group: '绑定',
                id: 'Tree_Binding',
                name: '数据绑定',
                enable: true,
                type: 'sortBinding',
                dataset: '',
                columns: [],
                tooltip: '组织架构树数据绑定,对应列：节点标识(数值，0开始)、节点名称、节点描述、父节点标识（数值，根节点-1）、节点图片（数值为默认图片，字符串为图片URL）'
            },
            {
                group: '绑定',
                id: 'FilterName',
                name: '过滤列名称',
                enable: false,
                type: 'text',
                value: '',
                default: '',
                link: 'filterName',
                tooltip: '绑定数据集，客户端过滤字段列名称'
            },
            {
                group: '绑定',
                id: 'FilterValue',
                name: '过滤列默认值',
                enable: false,
                type: 'text',
                value: '',
                default: '',
                link: 'filterValue',
                tooltip: '绑定数据集，客户端过滤字段默认值'
            }
        ].concat($.extend(true, [], Meta.commonProperties)),
        MapOption: function (option) {
            Util.linkOption(this.option, option);
        }
    };

    var pop = Chart.extend({
        constructor: function (layout) {
            this._layout = layout;
            this._element = null;
            this._lastdata = null;
            this._container = null;
            this._treeData = null;
            this._treeClass = "nodeTreeClass";
            this._treeId = "treeId-" + Util.newUUID();
            this._option = {
                Series: [],
                Events: [],
                Extend: $.extend(true, {}, property),
                Option: {
                    uuid: '',
                    class: '',
                    display: true,
                    lineWidth: 2,
                    lineColor: "#000000",
                    borderRadius: 3,
                    borderWidth: 1,
                    borderColor: "#000000",
                    backgroundColor: "#FFFFFF",
                    nodePadding: 5,
                    nodeWidth: 250,
                    nodeHeight: 100,
                    nodeImageWidth: 64,
                    nodeImageHeight: 64,
                    nodeNameSize: 12,
                    nodeDescSize: 12,
                    nodeNameColor: "#000000",
                    nodeDescColor: "#333333",
                    orientation: "NORTH",
                    levelSeparation: 30,
                    siblingSeparation: 30,
                    subTeeSeparation: 30,
                    stackChildren: false,
                    initScript: '',
                    disposeScript: ''
                }
            };
        },
        init: function (element) {
            try {
                this._container = element;
            } catch (e) {
                log.error(e);
            }
        },
        _bindEvent: function () {
            var _this = this;
            if (!this._filterDataHandle) {
                this._filterDataHandle = function (params) {
                    _this.filterDataHandle.call(_this, params);
                };
            }
            this._layout.removeListener("filterData", this._filterDataHandle);
            this._layout.addListener("filterData", this._filterDataHandle);
        },
        filterDataHandle: function (params) {
            var _this = this;
            var flag = false;
            var filterColumn = _.findWhere(this._option.Extend.option, {name: '过滤列名称'});
            var filterValue = _.findWhere(this._option.Extend.option, {name: '过滤列默认值'});

            if (filterColumn && filterValue
                && filterColumn.enable && filterValue.enable
                && filterColumn.value !== "" && filterValue.value !== ""
            ) {
                for (var prop in params) {
                    if (!params.hasOwnProperty(prop)) continue;
                    if (filterColumn.value === prop) {
                        filterValue.value = params[prop];
                        flag = true;
                    }
                }
            }
            if (flag && _this._lastdata) {
                _this.setData(_this._lastdata);
            }
        },
        _readProperty: function () {
            try {
                if (!this._option.Extend) return;
                Util.deepMapOption(property, this._option.Extend, this._option.Option);
            } catch (e) {
                log.error(e);
            }
        },
        _render: function () {
            var _this = this;
            if (!this._treeData || this._treeData.length === 0) return;
            this._treeId = "treeId-" + Util.newUUID();
            var option = {
                container: "#" + this._treeId,
                connectors: {
                    type: 'step',
                    style: {
                        "stroke-width": this._option.Option.lineWidth,
                        "stroke": this._option.Option.lineColor
                    }
                },
                rootOrientation: this._option.Option.orientation,
                levelSeparation: this._option.Option.levelSeparation,
                siblingSeparation: this._option.Option.siblingSeparation,
                subTeeSeparation: this._option.Option.subTeeSeparation,
                node: {
                    HTMLclass: this._treeClass
                }
            };
            var styleStr = "border: " + this._option.Option.borderWidth + "px solid " + this._option.Option.borderColor + ";";
            styleStr += "background-color: " + this._option.Option.backgroundColor + ";";
            styleStr += "border-radius: " + this._option.Option.borderRadius + "px;";
            styleStr += "width: " + this._option.Option.nodeWidth + "px;height:" + this._option.Option.nodeHeight + "px;";
            styleStr += "padding: " + this._option.Option.nodePadding + "px;";
            Util.createCSSSelector("#" + this._treeId + " .nodeTreeClass", styleStr);
            var styleStr1 = "font-size: " + this._option.Option.nodeNameSize + "px; color: " + this._option.Option.nodeNameColor + ";";
            Util.createCSSSelector("#" + this._treeId + " .node-name", styleStr1);
            var styleStr2 = "font-size: " + this._option.Option.nodeDescSize + "px; color: " + this._option.Option.nodeDescColor + ";";
            Util.createCSSSelector("#" + this._treeId + " .node-desc", styleStr2);
            var styleStr3 = "width: " + this._option.Option.nodeImageWidth + "px;height:" + this._option.Option.nodeImageHeight + "px;";
            Util.createCSSSelector("#" + this._treeId + " img", styleStr3);
            var config = [option].concat(this._treeData);
            window.Raphael = Raphael;
            $(this._container).empty();
            var $element = $('<div id="' + this._treeId + '"></div>');
            $element.appendTo(this._container);
            new Treant(config);
            //Util.setCommonMeta(this, this._container, this._option.Option);
            //Util.initChartLifeTime(this, this._container, this._option.Option);

            return $element;
        },
        example: function () {
            try {
                var personImage = "app/plugins/controls/common/organizational/images/person.png";
                var ceo = {
                        text: {
                            name: "Mark Hill",
                            desc: "Chief executive officer"
                        },
                        image: personImage
                    },
                    cto = {
                        parent: ceo,
                        text: {
                            name: "Joe Linux",
                            desc: "Chief Technology Officer"
                        },
                        stackChildren: true,
                        image: personImage
                    },
                    cbo = {
                        parent: ceo,
                        stackChildren: true,
                        text: {
                            name: "Linda May",
                            desc: "Chief Business Officer"
                        },
                        image: personImage
                    },
                    cdo = {
                        parent: ceo,
                        text: {
                            name: "John Green",
                            desc: "Chief accounting officer"
                        },
                        image: personImage
                    },
                    cio = {
                        parent: cto,
                        text: {
                            name: "Ron Blomquist",
                            desc: "Chief Information Security Officer"
                        },
                        image: personImage
                    },
                    ciso = {
                        parent: cto,
                        text: {
                            name: "Michael Rubin",
                            desc: "Chief Innovation Officer"
                        },
                        image: personImage
                    },
                    cio2 = {
                        parent: cdo,
                        text: {
                            name: "Erica Reel",
                            desc: "Chief Customer Officer"
                        },
                        image: personImage
                    },
                    ciso2 = {
                        parent: cbo,
                        text: {
                            name: "Alice Lopez",
                            desc: "Chief Communications Officer"
                        },
                        image: personImage
                    },
                    ciso3 = {
                        parent: cbo,
                        text: {
                            name: "Mary Johnson",
                            desc: "Chief Brand Officer"
                        },
                        image: personImage
                    },
                    ciso4 = {
                        parent: cbo,
                        text: {
                            name: "Kirk Douglas",
                            desc: "Chief Business Development Officer"
                        },
                        image: personImage
                    };

                this._treeData = [
                    ceo,
                    cto,
                    cbo,
                    cdo,
                    cio,
                    ciso,
                    cio2,
                    ciso2,
                    ciso3,
                    ciso4
                ];
                this._element = this._render();
            } catch (e) {
                log.error(e);
            }
        },
        _filterTable: function (option, table) {
            var filterColumn = _.findWhere(option, {name: '过滤列名称'});
            var filterValue = _.findWhere(option, {name: '过滤列默认值'});

            if (table && filterColumn && filterValue
                && filterColumn.enable && filterValue.enable
                && filterColumn.value !== "" && filterValue.value !== ""
            ) {
                var tableCopy = _.map(table, _.clone);
                return _.filter(tableCopy, function (row) {
                    return row[filterColumn.value] === filterValue.value;
                });
            }
            return table;
        },
        _bindData: function (data) {
            var bindProperty = _.findWhere(this._option.Extend.option, {type: 'sortBinding'});
            if (!bindProperty) return;
            var dataSetCode = bindProperty.dataset;
            var columns = bindProperty.columns;
            var table = data[dataSetCode];
            this._treeData = [];
            table = this._filterTable(this._option.Extend.option, table);
            if (table && table.length > 0 && columns.length >= 5) {
                var nodeIdKey = columns[0].ColumnName,
                    nodeNameKey = columns[1].ColumnName,
                    nodeInfoKey = columns[2].ColumnName,
                    nodePIdKey = columns[3].ColumnName,
                    nodeImageKey = columns[4].ColumnName,
                    rootParent = -1;
                var existChildren = _.filter(table, function (row) {
                    return parseInt(row[nodePIdKey]) === parseInt(rootParent);
                });
                if (existChildren && existChildren.length === 1) {
                    var rootRow = existChildren[0];
                    var imageStr = "app/plugins/controls/common/organizational/images/person" + rootRow[nodeImageKey] + ".png";
                    var imageUrl = isNaN(rootRow[nodeImageKey]) ? rootRow[nodeImageKey] : imageStr;
                    var rootNode = {
                        text: {
                            name: rootRow[nodeNameKey],
                            desc: rootRow[nodeInfoKey]
                        },
                        stackChildren: this._option.Option.stackChildren,
                        image: imageUrl
                    };
                    this._treeData.push(rootNode);
                    this._loopData(rootNode, rootRow, table, columns);
                }
            }
        },
        _loopData: function (pnode, prow, table, columns) {
            var _this = this;
            var nodeIdKey = columns[0].ColumnName,
                nodeNameKey = columns[1].ColumnName,
                nodeInfoKey = columns[2].ColumnName,
                nodePIdKey = columns[3].ColumnName,
                nodeImageKey = columns[4].ColumnName;
            var existChildren = _.filter(table, function (row) {
                return parseInt(row[nodePIdKey]) === parseInt(prow[nodeIdKey]);
            });
            _.each(existChildren, function (row) {
                var imageStr = "app/plugins/controls/common/organizational/images/person" + row[nodeImageKey] + ".png";
                var imageUrl = isNaN(row[nodeImageKey]) ? row[nodeImageKey] : imageStr;
                var node = {
                    parent: pnode,
                    text: {
                        name: row[nodeNameKey],
                        desc: row[nodeInfoKey]
                    },
                    stackChildren: _this._option.Option.stackChildren,
                    image: imageUrl
                };
                _this._treeData.push(node);
                _this._loopData(node, row, table, columns);
            });
        },
        setData: function (data) {
            try {
                this._lastdata = data;

                this._readProperty();
                if (data
                    && this._option.Binding
                    && this._option.Binding.length > 0
                    && this._option.Extend
                ) {
                    this._bindData(data);
                    this._readProperty();
                }
                this._element = this._render();
                this._bindEvent();
            } catch (e) {
                log.error(e);
            }
        },
        setOption: function (option) {
            try {
                return this._option = $.extend(true, {}, option);
            } catch (e) {
                log.error(e);
            }
        },
        getOption: function () {
            try {
                this._readProperty();
            } catch (e) {
                log.error(e);
            }
            return this._option;
        },
        setTheme: function (theme) {
            try {
            } catch (e) {
                log.error(e);
            }
        },
        resize: function () {
            try {
            } catch (e) {
                log.error(e);
            }
        },
        showLoading: function () {
            try {
                if (this._layout && this._layout.showLoading) {
                    this._layout.showLoading(this);
                }
            } catch (e) {
                log.error(e);
            }
        },
        hideLoading: function () {
            try {
                if (this._layout && this._layout.hideLoading) {
                    this._layout.hideLoading(this);
                }
            } catch (e) {
                log.error(e);
            }
        },
        dispose: function () {
            try {
                $(this._element).remove();
                this._layout.removeListener("filterData", this._filterDataHandle);
                //Util.disposeChartLifeTime(this, this._container, this._option.Option);

            } catch (e) {
                log.error(e);
            }
        },
        getElement: function () {
            return this._element;
        },
        getChart: function () {
            return this._element;
        }
    });

    return {
        Chart: pop,
        Property: property
    };
});